Skip to content

17 pprint美化打印

调试的时候,你用print()打印一个嵌套很深的字典或列表,输出全挤成一团,根本看不清。pprint(pretty print)就是来解决这个问题的,它会自动格式化输出,让数据结构一目了然。

一、基本用法

1.1 pprint()

python
from pprint import pprint

data = {
    "users": [
        {"name": "大志", "age": 28, "skills": ["Python", "LangChain", "Agent"]},
        {"name": "小明", "age": 25, "skills": ["Java", "Spring", "MySQL"]}
    ],
    "config": {
        "database": {"host": "localhost", "port": 5432},
        "cache": {"enabled": True, "ttl": 3600}
    }
}

# 普通print
print(data)
# {'users': [{'name': '大志', 'age': 28, 'skills': ['Python', 'LangChain', 'Agent']}, {'name': '小明', 'age': 25, 'skills': ['Java', 'Spring', 'MySQL']}], 'config': {'database': {'host': 'localhost', 'port': 5432}, 'cache': {'enabled': True, 'ttl': 3600}}}

# pprint
pprint(data)
# {'config': {'cache': {'enabled': True, 'ttl': 3600},
#             'database': {'host': 'localhost', 'port': 5432}},
#  'users': [{'age': 28,
#             'name': '大志',
#             'skills': ['Python', 'LangChain', 'Agent']},
#            {'age': 25,
#             'name': '小明',
#             'skills': ['Java', 'Spring', 'MySQL']}]}

二、pprint vs pp

2.1 pp()(3.14+推荐)

python
from pprint import pp, pprint

data = {"a": 1, "b": [2, 3, 4]}

# pp():sort_dicts默认为False(保持原始顺序)
pp(data)
# {'a': 1, 'b': [2, 3, 4]}

# pprint():sort_dicts默认为True(按键排序)
pprint(data)
# {'a': 1, 'b': [2, 3, 4]}

区别在于pp()保持字典原始顺序,pprint()默认按键排序。

三、格式化参数

3.1 indent:缩进

python
from pprint import pprint

data = {"a": {"b": {"c": 1}}}

pprint(data, indent=1)  # 默认
# {'a': {'b': {'c': 1}}}

pprint(data, indent=4)
# {   'a': {   'b': {   'c': 1}}}

3.2 width:行宽

python
from pprint import pprint

data = list(range(20))

# 默认宽度80
pprint(data, width=80)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

# 窄宽度,会换行
pprint(data, width=30)
# [0,
#  1,
#  2,
#  ...]

3.3 depth:深度限制

python
from pprint import pprint

data = {"a": {"b": {"c": {"d": {"e": 1}}}}}

# 只显示2层
pprint(data, depth=2)
# {'a': {'b': {...}}}

# 只显示3层
pprint(data, depth=3)
# {'a': {'b': {'c': {...}}}}

3.4 sort_dicts:字典排序

python
from pprint import pprint, pp

data = {"c": 3, "a": 1, "b": 2}

# pp():不排序(3.14+推荐)
pp(data)
# {'c': 3, 'a': 1, 'b': 2}

# pprint():排序(向后兼容)
pprint(data)
# {'a': 1, 'b': 2, 'c': 3}

# 强制不排序
pprint(data, sort_dicts=False)

四、pformat():获取字符串

python
from pprint import pformat

data = {"name": "大志", "scores": [90, 85, 92]}

# 返回格式化字符串
formatted = pformat(data)
print(formatted)

# 可以用于日志
import logging
logging.basicConfig(level=logging.DEBUG)
logging.debug(f"数据: {pformat(data)}")

五、PrettyPrinter类

python
from pprint import PrettyPrinter

# 创建自定义的PrettyPrinter
pp = PrettyPrinter(indent=2, width=60, depth=3)

data = {"a": {"b": {"c": {"d": 1}}}}
pp.pprint(data)

六、辅助函数

6.1 isreadable() / isrecursive()

python
from pprint import pprint

# 检查是否可读
pprint.isreadable([1, 2, 3])  # True
pprint.isrecursive([1, 2, 3])  # False

# 循环引用
data = [1, 2]
data.append(data)
pprint.isrecursive(data)  # True
pprint.isreadable(data)   # False

6.2 saferepr()

安全的repr,处理循环引用。

python
from pprint import saferepr

data = [1, 2]
data.append(data)

# repr会报错
# repr(data)  # RecursionError

# saferepr会用...代替循环引用
print(saferepr(data))
# [1, 2, <Recursion on list with id=...>]

七、实用场景

7.1 调试API响应

python
from pprint import pprint
import json

response = {
    "code": 200,
    "data": {
        "users": [
            {"id": 1, "name": "大志", "roles": ["admin", "user"]},
            {"id": 2, "name": "小明", "roles": ["user"]}
        ],
        "total": 2,
        "page": 1
    },
    "message": "success"
}

pprint(response)

7.2 查看复杂对象

python
from pprint import pprint

# 查看模块的所有属性
import os
pprint(dir(os))

# 查看对象的__dict__
class MyClass:
    def __init__(self):
        self.x = 1
        self.y = [2, 3]
        self.z = {"a": 4}

obj = MyClass()
pprint(vars(obj))
# {'x': 1, 'y': [2, 3], 'z': {'a': 4}}

7.3 格式化日志

python
from pprint import pformat
import logging

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

def log_config(config):
    logger.debug(f"配置:\n{pformat(config)}")

config = {"db": {"host": "localhost"}, "cache": {"ttl": 3600}}
log_config(config)

八、与print对比

特性printpprint
输出格式单行多行缩进
可读性
字典排序不排序默认排序
深度限制支持
循环引用报错用...代替

九、总结

pprint模块的核心:

函数用途
pprint()美化打印(向后兼容)
pp()美化打印(3.14+推荐)
pformat()返回格式化字符串
PrettyPrinter自定义打印器

调试的时候,把print()换成pprint(),数据结构立刻清晰可见。特别是打印API响应、配置文件、嵌套数据时,pprintprint好用太多。